Nous avons manipulé des variables avec des types simples : int, bool, float, str.
            Ce sont des conteneurs ne contenant qu'une valeur.
Nous avons manipulé aussi, sans vraiment l'étudier, des types construits (ou types abstraits) : liste, tuple.
            Ces types de données s'appellent des séquences.
        
Dans ce cours nous allons étudier deux types de séquence : les tableaux et les p-uplets. En python, les tableaux s'appellent les listes et les p-uplets s'appellent les tuples.
Séquence 
                Une séquence est une famille d'éléments indexée par les entiers strictement positifs
                inférieurs ou égaux à un certain entier, ce dernier étant appelé longueur de la séquence. 
                Ce terme de séquence est à rapprocher du concept de suite en mathématiques.
            
En informatique, un tableau est une structure de données représentant une
                séquence finie d'éléments auxquels on peut accéder efficacement par leur position,
                ou indice, dans la séquence. 
                C'est un type de conteneur que l'on retrouve dans un grand nombre de langages de programmation.
            
En Python, une séquence est une collection ordonnée d’objets qui permet d’accéder à ses éléments par leur numéro de position dans la séquence. Les listes et les tuples sont des séquences.
Il y a des points communs et des différences entre ces deux types.
p-uplet, tuple en python 
Un p-uplet est une séquence immutable, c'est-à-dire une suite indexée de valeurs (de n'importe quel type) que l'on ne peut pas modifier.
En Python, un p-uplet est de type tuple et est indexé à partir de 0.
                Dans un jeu vidéo, vous voulez identifier des lieux précis. 
                Pour cela, vous associer à chaque lieu un triplet (nom,abscisse,ordonnée). 
                Ainsi, le château du joueur A pourra ainsi est modélisé par une séquence comme
                ("fort_1", 15, -56.2). 
                Remarquez que les éléments du p-uplet sont de trois types différents ici.
            
Construire un objet tuple en python.
Un tuple est défini à l'aide de virgules et de parenthèses.
Les parenthèses sont nécessaires à la création d'un tuple vide pour le reste elle ne sont qu'une aide à la lecture.
L'utilisation de la virgule est nécessaire dès qu'on veut faire autre chose qu'un tuple vide.
tup1 = ()                     # un tuple vide
tup2 = (3, )                  # tuple avec un seul élément
tup3 = (1, 4, 5, 'moto', 4.6) # tuple avec cinq élément 
tup4 = 1, 4, 5, 'moto', 4.6   # même tuple sans parenthèse
print(type(tup1))         # pour accéder au type de l'objet
print(tup3 == tup4)       # test si les tuples tup3 et tup4 sont égaux ou non			Exécuter le script de l'exemple précédent.
En cas de problème avec votre IDE habituel (VSCode, Jupyter, Edupython, ...), vous pouvez utiliser ce trinket ; il vous suffit de saisir le script puis de l'exécuter en cliquant sur "►RUN".
Soient i un entier et t un tuple 
Pour accéder à l'élément i d'un tuple t on écrit
t[i]Le premier élément d'un tuple est indexé par 0.
Le dernier élément de t en Python est accessible avec l'index -1
t[-1]BONUS(non exigible)  
                        Pour afficher aux éléments entre l'index $i$ et l'index $j$ on utilise le slice :
t[i:j+1]pour afficher les éléments de deux en deux on pourra écrire :
t[i:j+1:2]On donne le tuple suivant : casse_all = ("chateauB", -10, 48.2, False) qui signifie que
                que le lieu considéré est nommé "châteauB", qu'il se situe au point de coordonnées $(-10;48.2)$ et qu'il n'est pas occupé par le
                joueur B.
Écrire les lignes de code qui affichent :
48.2
le dernier élément du tuple
(-10, 48.2)
"chateauB"
                Chaque joueur peut posséder plusieurs personnages actifs, chacun se situant dans un lieu donné. 
                Stockons l'ensemble des lieux occupés par les personnages du joueur C au tour 8 dans le tuple C_tour8.
            
                Supposons que C_tour8 = (("antre_orcs", 85, 36, True), ("chateau_C", -105.2, 23, True))
            
Écrire les lignes de code qui affichent :
                        "chateau_C", -105.2, 23, True
                    
                        "chateau_C"
                    
 
                        -105.2,23
                    
                Remarquer dans l'exemple précédent qu'un tuple peut en python contenir des éléments de différents types. 
                Certains éléments d'un tuple peuvent eux aussi être des tuples.
            
Un tuple est un objet immutable : on ne peut pas réaffecter ses éléments, supprimer un élément ou encore en ajouter.
Tester ces deux lignes de codes :
tup = (1, 4, 5, 'moto', 4.6)
tup[3] = 'vive le vélo !'
 Un tuple est itérable. 
                Cela signifie que l'on peut organiser une itération (boucle for) sur cette structure. 
Tester les deux scripts suivant séparément :
tup = ("puits_elfique", 78, 61.3)
for elt in tup :            # méthode 1, elt vaut tour à tour chaque élément de la séquence en respectant la position dans le tuple
	print(elt)              # print est utilisée à des fins d'observation de code ici : on lit le contenu de elt
for i in range(len(tup)):   # méthode 2, on parcourt les indices de la séquence
	print(tup[i])           # on lit le contenu de l'élément du tuple tup en position i
| Opérations/méthodes | Description | 
|---|---|
| Méthodes et opérations communes aux listes et tuples. | |
| elt intup | Renvoie Truesi un élément de tup est égal à elt,Falsesinon | 
| elt not intup | Renvoie Truesi aucun un élément de tup n'est égal à elt,Falsesinon | 
| len(tup) | Renvoie le nombre d'éléments de tup | 
| tup ==tup1 | Renvoie Truesi tup et tup1 sont de même type, ont la même longueur et ont des éléments égaux
                    deux à deux. | 
| tup[i] | Renvoie l'élément d'indice i de tup sachant que le premier élément a pour indice 0. | 
| tup[i:j] | Renvoie une partie de l'indice i à j, j étant non inclus | 
| tup.index(elt) | Renvoie l'indice de la première apparition de elt dans tup | 
| tup.count(elt) | Renvoie le nombre d'apparitions de elt dans tup | 
| tup1+tup2 | Renvoie une nouvelle séquence, séquence correspondant à la concaténation de tup1 suivie de tup2. | 
| tup*n | Renvoie une nouvelle séquence composée de la concaténation de tup avec lui même $n$ fois. | 
Voici deux tuples ci-dessous.
jours_1 = ('lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi')
jours_2 = ('samedi', 'dimanche')Utiliser les méthodes et les opérations du tableau pour tester les différentes questions :
                        Tester si samedi est un élément de jours_1.
                    
                        Donner la longueur de jours_2.
                    
                        Tester si jours_1 est égal à jours_2.
                    
                        Donner le deuxième élément de jours_1.
                    
                        Donner la partie de jours_1 entre le deuxième élément et le quatrième élément.
                    
                        renvoyer l'indice de dimanche dans jours_2.
                    
                        Renvoyer le nombre de samedi dans jours_2.
                    
                        Créer un tuple semaine par concaténation de jours_1 et de jours_2.
                    
Vous pouvez utiliser directement ce bac à sable Trinket.
En utilisant un parcours de tuple avec la présence d'un indice, écrire une fonction
                est_dans(element, tple) qui en argument reçoit un entier element et un tuple d'entiers
                tple, fonction qui renvoie un booléen indiquant la présence ou non de element dans tple.
            
on testera la fonction au moins avec les scripts suivants :
est_dans(4, (1, 2, 3, 4, 5, 6))
                        qui devrait renvoyer True.
est_dans(9, (1, 2, 3, 4, 5, 6))
                        qui devrait renvoyer False.
Avec le script suivant, avez-vous tou.te.s le même retour ?
import random 
tple = ()
for i in range(1000):
    r = random.randint(1, 1000)
    tple = tple + (r,)              # bien analyser le rôle de cette ligne
print(est_dans(400, tple))
                Voici un exercice à faire en autonomie pour tester votre maîtrise sur l'accès aux valeurs d'un tuple. 
                Cet exercice est issu du site collaboratif de la forge.
            
 En Python, une fonction qui renvoie plusieurs éléments, comme par exemple avec return a,b,c, renvoie un tuple.
def milieu(xA, yA, xB, yB) -> tuple:
    "Formule qui renvoie les coordonnées du milieu d'un segment"
    return (xA+xB)/2, (yA+yB)/2
    
print(type(milieu(1, 3, -1, 2)))Vous pouvez utiliser directement ce bac à sable Trinket.
                En utilisant milieu(1, 3, -1, 2), comment afficher seulement l'abscisse ? L'ordonnée ?
            
Écrire une fonction triangle_rect(n) qui renvoie un tuple où chaque élément est un tuple de longueur trois, ces tuples sont constitués de trois entiers a, b,c tels que $0<a\leq b\leq c < n$ et le triangle de cotés $a$, $b$
                et $c$ soit rectangle. Le tuple renvoyé doit contenir tous les triplets possibles.
Par exemple triangle_rect(20) renvoie le tuple
                ((3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15)).
            
                    Vous pouvez commencer par créer une première fonction est_rectangle qui prend en paramètre un tuple à
                    trois éléments (a, b, c) et renvoie True si le triangle dont plus grand côté a pour longueur c
                    est rectangle mais False sinon.
                
                Voici un exercice à faire en autonomie pour tester votre maîtrise sur la création d'un tuple comme renvoi d'une fonction. 
                Cet exercice est issu du site collaboratif de la forge.
            
Une séquence est un ensemble d'éléments indexés par des nombres entiers positifs.
Un p-uplet ou tuple est une séquence immutable indexée à partir de 0.
En python, un tuple est un objet le plus souvent délimité par des parenthèses dont les éléments sont séparés par des virgules.
                        Un tuple est un objet itérable, c'est-à-dire que l'on peut étudier chaque élément
                        séparément à chaque itération d'une boucle for.
                    
                        L'opération tuple[index] permet d'obtenir l'élément du tuple tuple en position
                        index.
                    
                        tuple.index(elt) renvoie l'index de la première apparition de l'élément elt dans
                        le tuple tuple.
                    
Tableau
Un tableau est une séquence mutable.
type list en Python
Une liste en Python est une séquence mutable de longueur variable qui est indexée à partir de 0.
En Python, une liste peut contenir des éléments de différents types.
                        Le nombre d'éléments d'une liste lst est donné par la fonction len,
                        en saisissant l'instruction len(lst).
                    
                lst = ['A', 5, 'NSI', 3.14, True, (4, -1)] est
                une liste.
            
                        Cette liste est formée de 6 éléments dont le type est ici soit str, soit int,
                        soit float, soit bool ou tuple.
                    
                        len(lst) renvoie 6.
                    
Chaque élément de la liste possède un index différent :
                                Le premier élément 'A' est indexé par $\color{blue}{0}$.
                            
                                Le deuxième élément 5 est indexé par $\color{blue}{1}$.
                            
...
                                Le dernier élément (4, -1) est indexé par $\color{blue}{5}$,
                                index dont la valeur peut être obtenue avec len(lst)-1.
                            
 
                        
                On peut accéder à la valeur de tout élément d'une liste à partir de son index (=position). 
                Plus précisément, l'élément d'une liste lst d'index
                i peut
                être obtenu avec lst[i].
            
En particulier :
                        Le premier élément d'une liste est accessible avec lst[0].
                    
                        Le dernier élément d'une liste est accessible avec lst[len(lst)-1]
                        mais aussi plus simplement avec lst[-1].
                    
                Soit la liste lst = ['A', 5, 'NSI', 3.14, True, (4, -1)].
            
                                lst[0] renvoie 'A'.
                            
                                lst[3] renvoie 3.14.
                            
                                lst[-1] renvoie (4, -1),
                                tout comme lst[len(lst)-1].
                            
 
                lst = [20, 'BAC', (2, 1, 0), 1.41, "NSI"]
            
                Une manière imagée et simplifiée de se représenter une liste est de la voir comme un
                meuble à tiroirs :
                 
            
                Chaque tiroir est repéré par un numéro : l'indice. 
                Chaque cellule de la liste correspond à un tiroir du meuble : 
                 
            
                Chaque tiroir peut contenir un objet : la valeur. 
                Chaque valeur de la liste correspond au contenu du tiroir correspondant : 
                 
            
                Lors d'un jeu vidéo basé sur l'exploration votre personnage doit apprendre progressivement
                les bribes essentielles de plusieurs langues étrangères. 
                Les langues successivement apprises sont stockées dans une liste langues. 
                Considérons une partie pour laquelle la liste est :
                langues = ["anglais", "hindi", "wolof", "arabe", "mandarin", "swahili", "espagnol", "gilbertin"]
            
Proposer une instruction qui permet d'obtenir le nombre de langues apprises dans la partie considérée.
                        Proposer une fonction polyglotte qui prend en paramètre une liste de langues et qui renvoie
                        le nombre de langues de cette liste. 
                        Par exemple, polyglotte(langues) doit renvoyer 8.
                    
Proposer une instruction qui permet d'obtenir la première langue apprise dans la partie.
                        Proposer une fonction en_cours qui prend en paramètre une liste de langues
                        et qui renvoie la dernière langue apprise dans la partie. 
                        Par exemple, en_cours(langues) doit renvoyer "gilbertin"".
                    
                        Proposer une fonction recente qui prend en paramètre une liste de langues
                        et qui renvoie l'avant-dernière langue apprise dans la partie. 
                        Par exemple, recente(langues) doit renvoyer "espagnol".
                    
                En JavaScript, cette notion de tableau est accessible avec la fonction array.
            
                Voici un exercice à faire en autonomie pour tester votre maîtrise sur l'accès aux valeurs d'une liste. 
                Cet exercice est issu du site collaboratif de la forge.
            
Une liste est définie à l'aide de crochets.
Pour initialiser en mémoire une liste nommée l et vide on écrira : l = [].
Une liste est un objet mutable : on peut réaffecter ses éléments, ou en ajouter.
                        Pour modifier l'élément en position pos de la liste lst afin qu'il prenne la valeur
                        valeur, il suffit d'utiliser une réaffectation en saisissant : lst[pos] = valeur.
                    
                        La méthode append permet d'ajouter à la fin d'une liste existante lst un élément
                        element_a_ajouter. On écrira : lst.append(element_a_ajouter). 
                        On parle alors de création en extension (puisque la liste est ainsi étendue).
                    
Tester les exemples suivants :
#1. Exécuter le code suivant :
liste = [1, 4, 9, 7, "moto", 4.5]
print("liste avant ajout", liste)    # print est utilisée à des fins d'observation de code
liste.append(35)                     # Ajout d'un élément à la fin de la liste
print("liste après ajout", liste)    # print est utilisée à des fins d'observation de code
liste[2] = 5                          # Modification de l'élément d'indice 2
print("liste après modification", liste) # print est utilisée à des fins d'observation de code
Reprendre le script précédent en remplaçant la liste liste par le tuple suivant :
tup = (1, 4, 9, 7, "moto", 4.5)Attention ! Vous allez rencontrer des messages d'erreur avec les tuples.
                Lors d'un jeu vidéo que vous créez, un personnage doit collecter progressivement des objets dans
                un sac. 
                Le sac est implémenté dans le jeu comme une liste nommée sac.
            
                        Quel script permet de créer la liste sac vide ?
                    
                        Quelle succession d'instructions suffit-il d'écrire pour que la liste sac 
                        contienne progressivement
                        les objets suivant en plus : "carte", "manteau" et
                        "gourde" ?
                    
                        Proposer une fonction rajouter qui prend en paramètre une liste sac
                        et une chaîne de caractères objet et qui renvoie la liste sac dans
                        laquelle l'objet objet a été rajouté comme dernier élément de la liste.
                    
                        Par exemple, rajouter(["pomme", "couteau"], "livre") doit renvoyer
                        ["pomme", "couteau", "livre"].
                    
                Pour ajouter un élément elt en fin d'une liste liste,
                on peut aussi effectuer la
                concaténation de listes avec l'opérateur + :
            
liste2 = liste + [elt]
                La différence avec la méthode append est que la concaténation conduit à la
                création d'une nouvelle liste,
                tandis que la méthode append modifie la liste initiale sans en créer de nouvelle (rien n'est renvoyé).
            
Vous pouvez visualiser la différence avec cet exemple :
liste1 = [3, 8, "mot", True]
liste2 = liste1 + ["qu'ont 4 N ?"]
print("liste1 :", liste1)   # liste1 est inchangée
print("liste2 :", liste2)   # liste2 est créée
liste1.append(3.14)
print("liste1 :", liste1)   # liste1 est modifiée
liste3 = liste1.append("pi")
print("liste1 :", liste1)   # liste1 est modifiée
print("liste3 :", liste3)   # liste3 est None car la méthode append ne renvoie rien !
                Voici un exercice à faire en autonomie pour tester votre maîtrise sur la création d'une liste par extension. 
                Cet exercice est issu du site collaboratif de la forge. 
                Si besoin, n'hésitez pas à travailler la version à compléter.
            
                Une liste est aussi un objet itérable. 
                Cela signifie que l'on peut organiser une itération (boucle for) sur cette structure. 
                On peut :
            
                        soit balayer une liste liste par ses index (ou positions) avec :
                    
for i in range(len(liste)):
    # action effectuée à chaque itération sur l'élément liste[i] 
                        soit balayer une liste liste par ses éléments (ou valeurs) avec :
                    
for elt in liste:
    # action effectuée à chaque itération sur l'élément elt, mais sans pouvoir avoir accès à son index 
                La liste de points obtenus à un jeu est stockée dans une liste points.
            
                Suite à une bonification, chaque point obtenu est doublé : la liste points doit donc être modifiée.
            
                        Pour répondre à ce problème concret, proposer une fonction doubler qui prend en paramètre une liste
                        et qui renvoie la liste où tous les valeurs ont été doublées.
                    
                                    Accéder aux éléments d'une liste lst à l'aide de crochets : lst[index] permet
                                    d'obtenir l'élément de la liste lst se trouvant en position indexée par index,
                                
                                    Balayer successivement l'ensemble des éléments d'une liste lst.
                                
                        Tester la fonction créée. 
                        Vérifier par exemple que doubler([15, 3, 16, 15.5]) renvoie
                        [30, 6, 32, 31].
                    
                Pour modifier les valeurs d'une liste par balayage, il faut balayer cette liste par ses indices
                et non par ses valeurs ! 
                Par exemple :
            
lst = [4, 3, 2]
for i in range(len(lst)):
    lst[i] = lst[i]*2
print(lst)
                Le script précédent affiche la liste lst = [8, 6, 4], comme attendu
                puisque chaque valeur est obtenue à partir de son indice puis le résultat du calcul devient la nouvelle
                valeur de la liste pour cette position. 
                En reprenant l'image du meuble à tiroirs :
            
                        Chacun des tiroirs est ouvert à partir de son indice (=numéro) i
                        grâce à la ligne for i in range(len(lst)):.
                    
                        Pour chaque tiroir, on regarde son contenu avec lst[i].
                    
                        Pour chaque tiroir, son contenu est modifié par son double avec lst[i] = lst[i]*2.
                    
Par contre :
lst = [4, 3, 2]
for elt in lst:
    elt = elt*2
print(lst)
                Le script précédent affiche la liste lst = [4, 3, 2] non modifiée. 
                En effet, en reprenant l'image du meuble à tiroirs :
            
                        Chaque contenu elt est sorti du tiroir
                        grâce à la ligne for elt in lst:.
                    
                        Chaque contenu est modifié par son double avec elt = elt*2
                    
MAIS ce contenu ne peut pas être remis dans le meuble car on sait pas dans quel tiroir le remettre ! Ainsi, la liste initiale reste inchangée !
Une entreprise décide d'augmenter le salaire annuel de 3% et d'octroyer une prime d'intéressement de 450€ à chacun de ses employés en fin d'année.
                L'ensemble des salaires annuels de l'année précédente est implémenté par une liste salaires.
            
                        Compléter la phrase suivante en précisant l'opération mathématique traduisant l'augmentation en pourcentage : 
                        Augmenter de 3% revient à ....
                    
                        Proposer une fonction augmenter qui prend en paramètre une liste stockant des nombres représentant
                        des salaires, qui effectue les deux augmentations prévues sur les salaires annuels et qui renvoie la
                        liste des salaires annuels après augmentation.
                    
                        Tester la fonction créée. 
                        Vérifier par exemple que augmenter([22200, 29436, 23736, 36144, 25272]) renvoie
                        [23316.0, 30769.08, 24898.08, 37678.32, 26480.16].
                    
                Il est possible de coder une image en nuance de gris : chaque pixel est codé par un nombre
                entier compris entre 0 (pour le noir) et 255 (pour le blanc). 
                Ainsi, l'image formée de 10 pixels  peut être représentée par la liste suivante :
                peut être représentée par la liste suivante :
                ligne_pgm = [80, 127, 255, 90, 201, 164, 0, 110, 128, 80]. 
                Il est possible de coder une image en noir et blanc : chaque pixel est codé par un bit :
                0 pour le blanc et 1 pour le noir. 
                Ainsi, l'image formée de 10 pixels  peut être représentée par la liste suivante :
                peut être représentée par la liste suivante :
                ligne_pbm = [1, 1, 0, 1, 0, 0, 1, 1, 0, 1].
                Le but est d'obtenir une fonction qui permet de convertir une image ligne en nuance de gris
                vers une image ligne en noir et blanc. 
                Pour cela, il suffit de considérer qu'un pixel en nuance de gris avec un nombre compris entre 0 et 127 sera
                sera codé en noir et qu'un pixel lié à un nombre compris entre 128 et 255 sera codé en blanc.
            
                La fonction pgm_vers_pbm suivante doit permettre une telle conversion. 
                Elle prend en paramètre une liste pgm de nombres entier compris entre 0 et 255.
                Elle construit une liste pbm progressivement par extension à partir d'une liste vide. 
                Cette liste contiendra finalement le codage en noir et blanc désiré. 
            
                        Compléter la fonction pgm_vers_pbm en s'aidant des commentaires :
                    
def pgm_vers_pbm(pgm: list) -> list:
    """
    pgm est une liste de nombres entiers compris entre 0 et 255
    renvoie une liste de 0 et de 1 correspondant à un codage en noir et blanc
    """
    pbm = ...        # liste désirée initialement vide 
    for ...:  # balayage des nombres de la liste en nuance de gris 
        if ... <= 127:
            ...      # ajout dans la liste désirée du bit de couleur correspondant (0 ou 1)
        else:
            ...      # ajout dans la liste désirée du bit de couleur correspondant (0 ou 1)
    return ...       # renvoi de la liste désirée.
                        Tester la fonction pgm_vers_pbm à l'aide de l'exemple proposé dans l'énoncé :
                    
>>> liste_pgm = [80, 127, 255, 90, 201, 164, 0, 110, 128, 80]
>>> pgm_vers_pbm(liste_pgm)
[1, 1, 0, 1, 0, 0, 1, 1, 0, 1]
                Vous avez obtenu un ensemble de notes, ensemble implémentés sour forme d'une liste. 
                Par exemple, si vous avez obtenu comme note 12, 8, 13, 9 et 16, l'ensemble des notes est implémenté par
                la liste [12, 8, 13, 9, 16].
            
                Vous aimeriez que seules les notes au-dessus de 10 soient prises en compte. 
                Pour cela, vous allez construire une fonction elaguer qui prend en paramètre une liste (de notes),
                crée une liste vide, puis ajoute à cette liste vide l'ensemble des notes au-dessus de 10 de la liste saisie en paramètre.
                Cette fonction elaguer renvoie finalement cette liste créée de notes au-dessus de 10.
            
                Le Delta encoding (ou codage par différence en français)
                est une des techniques pour compresser un tableau de valeurs. 
                Plutôt que de stocker la valeur elle-même, on stocke sa différence avec la valeur précédente. 
                Ainsi, lorsque les valeurs sont grandes, mais varient peu, les différences sont petites si bien que moins de bits
                sont nécessaires pour représenter en mémoire ces nombres.
            
                Supposons, par exemple, la liste des salaires d'une entreprise suivant :
                salaires = [1745, 1685, 1701, 1796, 1864, 1825]. 
                Plutôt que de stocker cette liste, il suffit de stocker la liste salaires_delta = [1745, -60, 16, 95, 68, -39].
            
                        Écrire une fonction delta prenant en paramètre une liste de nombres et renvoyant la liste obtenue par le codage
                        par différence.
                    
                        Tester la fonction écrite, par exemple avec la liste salaires = [1745, 1685, 1701, 1796, 1864, 1825].
                    
                Voici un exercice à faire en autonomie pour tester votre maîtrise sur le balayage des éléments d'une liste,
                soit par les positions, soit par les valeurs. 
                Cet exercice est issu du site collaboratif de la forge.
            
                Pour un jeu vidéo, le personne principal voit son niveau général augmenter de 1 dès que son nombre de points d'expérience
                atteint le carré d'un nombre entier. Par exemple, le personnage débutant commence avec un niveau de 0 lorsqu'il a 0 point d'expérience,
                il passe à 1 lorsqu'il atteint son premier point et reste à ce niveau jusqu'à l'obtention du quatrième point d'expérience où son
                niveau passe à 2 et ainsi de suite. 
                Pour gérer le lien entre niveau général du personnage et nombre de points d'expérience à obtenir pour le changement de niveau,
                vous décidez d'utiliser une liste lien où les valeurs sont les carrés des positions
                ; ainsi, l'index est le niveau général et la valeur associée est le nombre de points d'expérience nécessaire pour atteindre ce niveau.
                Si vous limitiez le niveau maximal à 4, votre liste serait lien = [0, 1, 4, 9, 16]. 
                Comme vous voulez dans un premier temps proposer un niveau maximal de 100, la liste lien contient 101 valeurs. 
                Plutôt que de saisir l'ensemble des valeurs directement, vous avez pensé utiliser une création par extension : partir d'une liste
                vide et rajouter à sa fin un carré jusqu'au carré de 100, comme le script suivant :
            
lien = []               # liste vide initialement
for i in range(101):
    lien.append(i**2)   # ajout du carré en fin de liste
                Ce script convient mais le temps d'exécution est "assez long" puisque la liste lien est modifiée 101 fois. 
                Pour être plus rapide, une amie vous annonce qu'il est possible de créer la même liste en une seule fois en utilisant
                la structure suivante, pour réaliser une création en compréhension :
            
lien = [i**2 for i in range(101)]       # liste directement créer en suivant une formule
                Il est possible de créer une liste en compréhension avec une structure de la forme : 
                [formule for variable in ensemble (éventuellement avec une condition supplémentaire avec if condition)]
            
                Voici différents script où une liste est créée en compréhension. 
                À chaque script, deviner la liste obtenue puis le vérifier en exécutant le script proposé dans un IDE.
            
liste1 = [2*x for x in range(10)]import math
liste2 = [x**2 for x in range(10)]
liste3 = [math.sqrt(x) for x in liste2]liste = [3, -8, "mot", True, 4.5, 6]
liste4 = [x**2 for x in liste if type(x) == int]
                Dans le dernier cas de l'exercice précédent, remarquer que la condition portant sur la variable est saisie grâce à un if
                et ce après le in ensemble.
            
Dans cet exercice, vous devez écrire deux scripts Python qui créent la liste des entiers de 0 à 10000 de deux méthodes différentes :
En extension.
En compréhension.
                    Dans cet exercice, vous pouvez vous servir ou pas du fait que
                    a%2 renvoie le reste de la division euclidienne de a par 2.
                
Créer en extension une liste qui contienne les nombres pairs inférieurs à 10000.
Créer en compréhension une liste qui contienne les nombres pairs inférieurs à 10000.
Créer en compréhension une liste qui contienne les nombres impairs inférieurs à 10000.
Tableaux et fonctions
Voici une fonction dont l'en-tête est incomplète ; il manque le type de retour
def test(a: list) -> ...:
	return [x**2 for x in a if x > 0], [x for x in a if x > 10]
# une liste pour tester la fonction
a = [-4, -3, -2, 0, 1, 5, 9, 11]
		Décrire le type du retour de la fonction et le rajouter à l'en-tête.
Expliquer ce que fait cette fonction et le rajouter comme documentation à cette fonction.
                Le personnage d'un jeu vidéo possède un certain nombre d'objets dont l'ensemble est modélisé par la liste
                besace. 
                Supposons que ce personnage possède les objets de la liste suivante :
                besace = ["armure", "canne", "heaume", "cuir", "sérum", "chapeau", "pain"].
            
                Proposer un script qui permet de créer, si possible par compréhension, la liste besace_C des objets
                dont le nom commence par la lettre "c".
            
                Voici un exercice à faire en autonomie pour tester votre maîtrise sur la création d'une liste par compréhension. 
                Cet exercice est issu du site collaboratif de la forge. 
                Travaillez la Construction par compréhension.
            
Un tableau ou liste en python est une séquence mutable indexée à partir de 0.
En python, une liste est un objet délimité par des crochets dont les éléments sont séparés par des virgules.
                        Une liste est un objet itérable, c'est-à-dire que l'on peut étudier chaque élément
                        séparément à chaque itération d'une boucle for.
                    
                                Avec for i in range(len(lst)) on peut balayer la liste lst à partir
                                des index i.
                            
                                Avec for elt in lst on peut balayer la liste lst à partir
                                des valeurs elt.
                            
                        On peut créer une liste lst par extension en commençant par exemple par une liste vide
                        lst = [], puis par itérations successives en rajoutant les éléments un à un en fin de liste
                        avec lst.append(element).
                    
                        Un peut créer une liste lst par compréhension en utilisant la structure
                        [formule for variable in ensemble (if condition)].
                    
Le but de cet exercice est de découvrir comment créer une copie indépendante d'une liste.
On considère le script suivant :
liste1 = [4, 6, 5, 7]
liste2 = liste1
                                Sans exécuter le script, devinez quel sera le contenu de la variable
                                liste2.
                            
Vérifier en exécutant le script.
L'instruction suivante est effectuée à la suite du script précédent :
liste2.append(3)
                                Sans exécuter le script complété, devinez quel sera le contenu de la variable
                                liste2.
                            
                                Sans exécuter le script complété, devinez quel sera le contenu de la variable
                                liste1.
                            
                                Vérifier en exécutant le script complété. 
                                Expliquer en quoi la liste liste2
                                n'est pas une copie indépendante de la liste liste1.
                            
On considère désormais le script suivant :
liste3 = [4, 6, 5, 7]
liste4 = liste3.copy()
                                Sans exécuter le script, devinez quel sera le contenu de la variable
                                liste4.
                            
Vérifier en exécutant le script.
L'instruction suivante est effectuée à la suite du script précédent :
liste4.append(3)
                                Sans exécuter le script complété, devinez quel sera le contenu de la variable
                                liste4.
                            
                                Exécuter le script complété afin de vérifier que liste4
                                est bien une copie indépendante de liste3.
                            
                On considère la liste liste1 = [7, 5, 6, 3, 2, 4, 7, 3, 8].
            
                        Compléter le code ci-dessus afin que la liste liste2 
                        soit créée par compréhension et possède le même contenu 
                        que la liste liste1.
                    
liste2 = [... for ... in ...]
                        La liste liste2 est-elle une copie indépendante de la liste 
                        liste1 ? Vérifier sur des tests.
                    
                Pour créer une copie indépendante liste2 d'une liste
                liste2, il ne FAUT PAS écrire :
                liste2 = liste1 !
            
                Pour créer une copie indépendante liste2 d'une liste
                liste2, il suffit :
            
                        soit d'utiliser la méthode copy
                en écrivant liste2 = liste1.copy().
                    
                        soit de créer la seconde liste par compréhension 
                        en écrivant liste2 = [elt for elt in liste1].
                    
Lors du chapitre sur les dictionnaires, une explication sera donnée.
                On peut appliquer aux listes toutes les méthodes, fonctions et opérations des tuples. 
                En tant qu'objet mutable, les listes possèdent en plus des fonctions et des méthodes propres. 
                Voici les méthodes, fonctions et opérations à connaître sur les listes :
            
| Opérations/méthodes | Description | 
|---|---|
| Méthodes et opérations communes aux listes et tuples. | |
| elt inlst | Renvoie True si un élément lst est égale à elt, False sinon | 
| elt not inlst | Renvoie True si aucun un élément de lst n'est égale à elt, False sinon | 
| len(lst) | Renvoie le nombre d'éléments de lst | 
| lst1 ==lst2 | Renvoie True si lst1 et lst2 sont de même type, ont la même longueur et ont des éléments égaux deux à deux. | 
| lst[i] | Renvoie l'élément d'indice idelst. Le premier élément a pour indice 0. | 
| lst[i:j] | Renvoie une partie de la liste lst, celle entre les indicesiàj,jnon inclus | 
| lst.index(elt) | Renvoie l'indice de la première apparition de eltdanslst | 
| lst.count(elt) | Renvoie le nombre d'apparitions de eltdanslst | 
| lst1 +lst2 | Renvoie une nouvelle liste, liste résultant de la concaténation de lst1 et de lst2. | 
| lst*n | Renvoie une nouvelle liste résultant de la concaténation de lstavec lui-mêmenfois. | 
| Méthodes et opérations applicables aux listes (mais pas aux tuples). | |
| lst.append(elt) | Ajoute l'élément eltà la fin de la listelst. | 
| lst[i] = elt | Modifie la liste lsten affectant la valeureltà la case d'indicei.Attention, cette case doit exister. | 
| lst.insert(i, val) | Insère l'élément valdans la listelstà l'indicei.Cette méthode décale les indices suivants. | 
| lst.remove(elt) | Supprime de la liste lstle premier élément dont la valeur est égale àelt | 
| lst.pop(i) | Enlève de la liste l'élément à la position iet renvoie sa valeur.En l'absence d'élément en position i, c'est le dernier élément qui est supprimé et renvoyé | 
| lst.sort() | Modifie la liste lsten la triant | 
| lst.reverse() | Modifie la liste lsten inversant l'ordre de ses éléments | 
| lst2 = lst1.copy() | Copie la liste lst1en une indépendantelst2 | 
Voici un programme en python :
import random 
liste = [random.randint(1, 6) for i in range(1000)] 
                        Que contient la liste liste ?
                    
                        Combien d'éléments contient cette liste ?
                        Vérifier en utilisant un script Python.
                    
Écrire un script Python qui renvoie une liste formé de six nombres entiers :
                            Le premier entier donne le nombre de 1 dans la liste liste.
                            
                            Le deuxième entier donne le nombre de 2 dans la liste liste.
                            
...
                            Le sixième entier donne le nombre de 6 dans la liste liste.
                            
                            Utiliser la la méthode count.
                        
Quelle instruction écrire pour enlever l'avant-dernier terme de la liste ?
Quelle instruction écrire pour enlever la première occurrence du nombre 6 de la liste ?
Le but de cet exercice est d'écrire une fonction "compter" sans utiliser count
Écrire une fonction compter(element, liste) qui a pour paramètres un entier element et une liste
                        d'entiers liste qui renvoie le nombre d'occurrences de element dans liste.
Utiliser la fonction compter pour refaire l'exercice précédent.
  Prolongement possible : remplacer element par une liste d'éléments dans les arguments de la fonction compter.
                        On peut ajouter en fin d'une liste lst l'élément elt avec la méthode append
                        avec lst.append(elt).
                    
                        L'opération lst[index] permet d'obtenir l'élément de la liste lst en position
                        index.
                    
                        liste.index(elt) renvoie l'index de la première apparition de l'élément elt dans
                        la liste liste.
                    
                        La fonction len permet de connaître le nombre d'éléments d'une liste lst avec
                        len(lst).
                    
                        On peut supprimer et renvoyer l'élément en position i d'une liste lst avec la méthode pop
                        avec lst.pop(i).
                    
                        On peut trier une liste lst en utilisant la méthode sort
                        avec lst.sort().
                    
                        On peut inverser l'ordre des éléments d'une liste lst en utilisant la méthode reverse
                        avec lst.reverse().
                    
                        On peut créer une copie indépendante lst2 d'une liste lst en utilisant la méthode copy()
                        avec ls2 = lst.copy().
                    
Les éléments d'un tableau peuvent être également un tableau. Ce type d'objet rappelle un objet mathématiques que vous verrez plus tard qui s'appelle une matrice. Cet objet est utilisé dans de nombreux domaines, notamment dans le traitement des images. Une image est une matrice de pixels.
Matrices
On appelle matrice un tableau de tableaux dont chaque tableau à la même longueur.
Chaque élément d'une matrice A est noté $a_{i,j}$ où $i$ est le numéro de ligne et $j$ le numéro de colonne.
On représente une matrice de taille $n$,$m$ en mathématiques ainsi :
$A = \begin{pmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,m} \\ a_{2,1} & a_{2,2} & \cdots & a_{2,m} \\ \vdots & \vdots & \ddots & \vdots \\ a_{n,1} & a_{n,2} & \cdots & a_{n,m} \end{pmatrix}$
En Python, une matrice est une liste de listes de même longueur.
Pour accéder à un élément organisé en liste de listes, on utilise une notation avec un double crochets. Le premier indice pointe la ligne et le deuxième indice pointe la colonne.
Si notre matrice contient $n$ listes de $m$ éléments on peut la voir ainsi :
$L= \begin{pmatrix} L[0][0] & L[0][1] & \cdots & L[0][m-1] \\ L[1][0] & L[1][1] & \cdots & L[1][m-1] \\ \vdots & \vdots & \ddots & \vdots \\ L[n-1][0] & L[n-1][1] & \cdots & L[n-1][m-1] \end{pmatrix}$
Pour accéder à l'élément j de la i-ème liste de L on écrira :
L[i][j]
L = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]Ici , L[1][2] = 7
L = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]Le premier élément de la liste L est la liste [1, 2, 3, 4] ;
                pour l'afficher on écrit : L[0].
            
 Le troisième élément de cette liste [1, 2, 3, 4], notée L[0], est 3 ; pour y accéder
                nous utiliserons L[0][2]
Afficher le quatrième élément du deuxième élément de la liste.
Afficher le deuxième élément du troisième élément de la liste.
Afficher l'élément indexé 0 du deuxième élément de la liste.
Afficher L[2][3].
Ajouter la valeur 26 à la deuxième liste. L est-elle encore une matrice ?
                Créer une fonction mat_nulle qui prend en paramètre deux nombres entiers n et m et
                qui renvoie une matrice de n lignes et m colonnes formée uniquement de 0.
            
                Par exemple mat_nulle(4, 3) renvoie le tableau de tableaux 
                [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]].
            
Vérifier que vous avez des lignes indépendantes les unes des autres en exécutant le code suivant :
mat = mat_nulle(5, 4)
print(mat)
mat[0][2] = 6 # 6 mis en première ligne et troisième colonne de la matrice
print(mat)
assert mat == [[0, 0, 6, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]                    On peut se servir de données structurées en liste de listes sans que ce soit des matrices.
Écrire une fonction matriceAlea(n: int, m: int) -> list en langage Python qui renvoie une matrice à
                n lignes et m colonnes d'entiers aléatoires entre 0 et 100.
            
                Proposer une fonction entiers_en_matrice qui prend en paramètres deux nombres entiers
                n et m et qui renvoie la matrice formée par tous les nombres entiers compris entre
                0 et $m\times n-1$ de telle sorte que ces nombres entiers soient rangés par ordre croissant lors
                du parcours de la matrice suivant chaque ligne de "haut en bas". 
                Par exemple, entiers_en_matrice(3, 5) renvoie [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9], [10, 11, 12, 13, 14]]
                et entiers_en_matrice(4, 1) renvoie [[0], [1], [2], [3]]
            
                Une image en noir et blanc peut être codée pixel par pixel informatiquement par un tableau en deux dimensions formés de 0 et de 1,
                où le 1 code noir et 0 blanc. 
                Voici une telle image :  
            
Proposer un tableau 2D en langage Python représentant le codage en noir et blanc de l'image ci-dessus.
                        Le négatif d'une image en noir et blanc est une image de même taille où dans la représentation informatique
                        les 1 ont été changé en 0 et où les 0 ont été changé en 1. 
                        Proposer une fonction creer_negatif qui prend en paramètre un tableau 2d sous forme de liste
                        de listes et qui renvoie le tableau 2D où tous les 1 et les 0 ont été changés en leur complémentaire.
                    
Tester la fonction sur le tableau 2D représentant l'image ci-dessus.
                Le chiffrement Playfair a été développé au XIXème siècle et utilisé par l'armée britannique
durant les guerres du XXème siècle, est basé sur le chiffrement de paires de lettres.
                On dispose les lettres de l'alphabet (le W étant exclu dans l'utilisation 
                de ce chiffrement en France) dans une grille carrée 5X5 comme par exemple 
                le tableau ci-dessous : 
                
                Source : vikidia.org
            
                        On considère une liste lettres de 25 lettres différentes de l'alphabet. 
                        Le but est de construire à partir d'elle une grille de 5 par 5, 
                        comme celle utilisée pour le chiffrement de playfair.
                    
                        Compléter la fonction creer_carre_playfair ci-dessous qui prend en paramètre une liste de 25 lettres 
                        différentes de l'alphabet et renvoie un tableau 2D représentant 
                        le carré de chiffrement de Playfair associé.
                    
def creer_carre_playfair(liste_clef):
    carre = [[...] for j in range(...)] # création d'une grille nulle de 5 par 5
    for i in range(25):
        carre[...][...] = liste_clef[i]
    return ...
                            Les opérateurs % et 
                            // de la division euclidienne peuvent être utiles ici.
                        
Voici un test possible :
>>> lettres = ['P', 'L', 'A', 'Y', 'F', 'I', 'R', 'B', 'C', 'D', 'E', 'G', 'H', 'J', 'K', 'M', 'N', 'O', 'Q', 'S', 'T', 'U', 'V', 'X', 'Z']
>>> creer_carre_playfair(lettres)
[['P', 'L', 'A', 'Y', 'F'], ['I', 'R', 'B', 'C', 'D'], ['E', 'G', 'H', 'J', 'K'], ['M', 'N', 'O', 'Q', 'S'], ['T', 'U', 'V', 'X', 'Z']]
                        Dans le script de la fonction précédente creer_carre_playfair, 
                        rajouter deux préconditions sur le 
                        paramètre liste_clef afin de vérifier que cette 
                        liste ait bien 25 éléments mais pas la lettre W.
                    
                        Donner le code Python de la fonction ligne_colonne 
                        qui prend en paramètres une lettre majuscule carac et un carré de chiffrement carre
                        créé par la fonction creer_carre, et qui renvoie les 
                        coordonnées de la lettre carac dans le carré de 
                        chiffrement carre. 
                        On suppose ici que la lettre majuscule apparaît toujours dans le carré.
                        Deux tests proposés :
                    
>>> carre = [['P', 'L', 'A', 'Y', 'F'], ['I', 'R', 'B', 'C', 'D'], ['E', 'G', 'H', 'J', 'K'], ['M', 'N', 'O', 'Q', 'S'], ['T', 'U', 'V', 'X', 'Z']]
>>> ligne_colonne('A', carre)
(0, 2)
>>> ligne_colonne('N', carre)
(3, 1)                    
                    Si vous désirez des explications sur le fonctionnement du chiffrement de Playfair, n'hésitez pas à consulter ce site très riche en cryptanalyse : 
                    apprendre-en-ligne.net.
                    En fouillant dans ce site, vous pourrez découvrir des techniques algorithmiques pour 
                    déchiffrer un message chiffré et même des scripts Python pour un déchiffrement automatique.
                
                Voici un exercice à faire en autonomie pour tester votre maîtrise sur la manipulation
                de liste de listes. 
                Cet exercice est issu du site collaboratif de la forge. 
            
Une matrice est un tableau de tableaux dont chaque tableau à la même longueur.
                        Si tab est une liste de listes, on peut accéder à l'élément de la ligne i
                        (indexée à partir de 0) se trouvant à l'index j avec le code suivant :
                        tab[i][j].
                    
Le but de cet exercice est de représenter un jeu de 32 cartes.
 
            Un jeu de 32 cartes est composé de :
quatre couleurs : pique, cœur, carreau, trèfle,
huit valeurs : roi, dame, valet, 1, 10, 9, 8, 7.
Modélisation du problème.
Comment modéliser une carte en Python ?
Comment modéliser un jeu de cartes ?
Implémentation en Python.
Le but est d'implémenter un jeu de 32 cartes et se doter de fonctions qui permettent interagir avec ce jeu.
Il faut typer vos fonctions. Exemple :
                                    creation_jeu32(couleur: tuple, valeur32: tuple) -> list
                                
Il faut écrire une aide explicative docstring, entre " ", ou entre
                                    """ """"  (si l'aide fait plusieurs lignes).
                                
Dans cette partie, on suppose disposer de deux tuples :
                                couleur = ("pique", "cœur", "carreau", "trèfle").
                                
                                valeur32 = ("Roi", "Dame", "Valet", 1, 10, 9, 8, 7).
                                
                            Dans cette partie une carte sera donnée comme un tuple formé d'une valeur et d'une couleur, 
                            comme par exemple la carte ("Dame", "cœur").
                        
 Créer une fonction
                                creation_jeu32(couleur: tuple, valeur32: tuple) -> list qui retourne une liste de 32 cartes.
                            
Vérifier que le jeu créé avec la fonction précédente possède bien 32 cartes.
On veut pouvoir mélanger le jeu de 32 cartes. 
                            Il existe une fonction shuffle de la bibliothèque random qui mélange "sur place" les éléments 
                            d'une liste : random.shuffle(liste) modifie ainsi la liste liste en 
                            mélangeant aléatoirement l'ordre de ses éléments, sans créer une nouvelle liste. 
                            Écrire une fonction melange(jeu: list) -> list qui renvoie le jeu de cartes 
                            mélangées.
                            
                                On veut pouvoir tirer une carte au hasard du jeu. 
                                Si le jeu est mélangé, cela peut être la première carte. 
 
                                Il faut ed plus penser à retirer la carte du jeu. 
                                Créer ainsi une fonction 
                                carte_hasard qui prend en paramètre une liste 
                                jeu et renvoie un tuple formé de la carte tirée et de la liste des cartes 
                                restant dans le jeu une fois la carte tirée.
                            
On veut pouvoir créer une "main" de 5 cartes. 
                                Une main signifie un ensemble de cartes. 
 
                                Écrire une fonction main(nombre_cartes: int, jeu: list) -> tuple 
                                qui renvoie une main formée du nombre de cartes et la liste formée du reste 
                                des cartes du jeu. 
                            
Ne pas oublier de retirer la main créée du jeu de 32 cartes renvoyé comme reste.
Autre modèle possible.
On veut pouvoir comparer des cartes pour réaliser par exemple des jeux.
Modélisation
Comment modéliser la "force" d'une carte ?
Comment modéliser le jeu de cartes avec la force de chaque carte ?
Implémentation en Python
Écrire une fonction force(carte: tuple) -> int: qui renvoie la "force" de la carte.
Écrire une fonction jeu_force(jeu) qui renvoie le jeu des cartes associées à
                                        leur force.
On veut comparer deux cartes. Écrire une fonction en Python
                                        compare(carte1: tuple, carte2: tuple) -> tuple
                                        qui renvoie la carte avec la force la plus élevée.
                                    
Inventer une notion de distance entre deux cartes. Écrire une fonction
                                        distance(carte1: tuple, carte2: tuple) -> int qui 
                                        renvoie la "distance" entre deux cartes.
                                    
Le prolongement de cette activité est la création d'un jeu (bataille, rami, blackjack, poker, pyramide, etc.). La création d'un jeu pourra être développée dans le cadre de votre projet.
Faire une recherche sur le web sur la notion de carré magique. Un carré magique d'ordre 3 est une matrice de 3 lignes et trois colonnes dont la somme des lignes, des colonnes et des diagonales fait le même nombre.
L = [[2, 7, 6],
     [9, 5, 1],
     [4, 3, 8]]	Écrire un script Python qui vérifie que ce carré est magique. Le prolongement de cet exercice est la recherche de carrés magiques à partir de carrés à compléter.
Python considère une phrase comme une séquence. Vous pouvez réaliser des essais avec cette citation célèbre du philosophe Confucius : "Je ne cherche pas à connaître les réponses, je cherche à comprendre les questions." De quelle type de séquence se rapproche-t-on? De la liste et/ou du tuple ? Faire des tests à partir de vos connaissances en python.
# -*- coding: utf-8 -*-
citation="Je ne cherche pas à connaître les réponses, je cherche à comprendre les questions."
# Quelques tests à faire :
citation[3]
citation[4] = 'z'
citation.append('!')
# En chercher d'autres 
En utilisant la méthode count(elt), compter le nombre de 'a' dans la citation, le nombre de 'e', le nombre de voyelles, etc. 
Il existe pour les listes des méthodes très intéressantes dans le traitement des chaînes de caractères.
                Ce sont les méthodes split() et join().
            
                    Penser à également utiliser la fonction type afin de vérifier le type des variables créées.
                
Exécuter le code suivant en faisant afficher le contenu des différents objets :
# -*- coding: utf-8 -*-
citation = "Je ne cherche pas à connaître les réponses, je cherche à comprendre les questions."
liste = citation.split(" ")
phrase2 = " ".join(liste)
# Afficher le contenu des différentes variables afin de comprendre les méthodes split et join
# Faire des tests sur d'autres phrases Vous pouvez utiliser directement ce bac à sable Trinket.
                        Quel est le rôle des méthodes split et join ?
                    
                        En utilisant ces principes, comment faire pour créer une liste de mots à partir de la
                        chaîne de caractères suivante : chaine = "un,deux,trois,quatre,cinq" ?
                    
Extraire des groupes aléatoires.
L'objectif est de créer une fonction groupe(taille, nom_csv) qui prend pour argument un entier : 
                taille correspondant à la taille des groupes voulus et une chaîne de 
                caractères nom_csv correspondant au nom du fichier csv qui renvoie 
                la répartition des groupes à la bonne taille de manière aléatoire.
Le matériel nécessaire se compose d'un fichier csv téléchargeable ici.
Chaque individu possède trois attributs Nom, Prenom et Race (orc ou gobelin).
Les individus sont des "peaux vertes" constitués d'orcs et de gobelins.
Quelques aides à la réalisation de ce travail :
La bibliothèque random sert en Python à générer des nombres aléatoires :
                                Vous pouvez utiliser directement ce
                                bac à sable Trinket pour découvrir
                                la fonction randrange du module random.
                            
la bibliothèque csv sert à manipuler des fichier csv, vous pouvez tester ce code pour appréhender les outils
                            nécessaires à votre travail :
import csv
verts = open("peaux_vertes.csv", "r")   # ouvre le fichier peaux_vertes.csv en mode lecture et le met en mémoire dans la variable verts
reader = csv.reader(verts)              # transforme la variable verts en un objet itérable
for line in reader:                     # lecture ligne à ligne du contenu de l'itérable (donc du tableau csv)
    print(line[1])                      # Affiche le second élément de la ligne (donc l'élément en seconde colonne)
groupe.close()                          # referme correctement le fichier ouvert
Prolongement possible :
Réécrire la fonction précédente qui ajoute un numero de groupe à chaque groupe.
Faire en sorte de réécrire un csv avec la liste des élèves avec leur numéro de groupe.
Dans la gestion d'un jeu vidéo, vous avez stocké l'ensemble des châteaux visités par deux joueurs dans deux tuples différents :
joueur_1 = ("chateau_ride", "chateau_tot", "chateau_mat", "chateau_no", "chateau_que_sain", "chateau_plat")
joueur_2 = ("chateau_mat", "chateau_car", "chateau_lier", "chateau_ride", "chateau_no", "chateau_paz")Utiliser les méthodes et les opérations du tableau pour tester les différentes questions :
                        Tester si le joueur 1 a visité ou non le château "chateau_paz".
                    
Quel est le premier château visité par le joueur 1 ?
Combien de châteaux a visité le joueur 1 ?
Quel est le dernier château visité par le joueur 1 ?
Tester si les deux joueurs ont visités les mêmes châteaux.
Donner l'ensemble des noms des châteaux visités par le joueur 2 entre le deuxième château visité et le cinquième.
                        renvoyer l'indice de "chateau_ride" dans le tuple joueur_2.
                    
                        Renvoyer le nombre de "chateau_mat" dans joueur_1 puis dans joueur_2.
                    
                        Créer un tuple ensemble par concaténation de joueur_1 et de joueur_2. 
                        Ce tuple possède-t-il des doublons ?
                    
                        "chateau_paz" in joueur_1 renvoie False
                        : le joueur 1 n'a pas visité ce château.
                    
                        joueur_1[0] renvoie "chateau_ride"
                        : c'est le premier château visité par le joueur 1.
                    
                        len(joueur_1) renvoie 6
                        : le joueur 1 a visité 6 châteaux.
                    
                        joueur_1[-1] tout comme
                        joueur_1[len(joueur_1)] renvoie "chateau_plat"
                        : c'est le dernier château visité par le joueur 1.
                    
                        joueur_1 == joueur_2 renvoie False
                        : les deux joueurs n'ont pas visité les mêmes châteaux.
                    
                        joueur_2[1:5] renvoie "chateau_car","chateau_lier","chateau_ride","chateau_no"
                        : ce sont le nom des châteaux visités par le joueur 2 entre le deuxième et le cinquième.
                    
                        joueur_2.index("chateau_ride") renvoie 3
                        : "château_ride" est le quatrième château visité par le joueur 2.
                    
                        joueur_1.count("chateau_mat") renvoie 0
                        et joueur_2.count("chateau_mat") renvoie 1
                        : "chateau_mat" a été visité par le joueur 2 mais pas par le joueur 1.
                    
                        ensemble = joueur_1+joueur_2 réuni comme tuple l'ensemble des châteaux visités. 
                        Les châteaux visités par les deux joueurs apparaissent deux fois : 
                        Voici le contenu du tuple ensemble : ('chateau_ride',
                            'chateau_tot',
                            'chateau_mat',
                            'chateau_no',
                            'chateau_que_sain',
                            'chateau_plat',
                            'chateau_mat',
                            'chateau_car',
                            'chateau_lier',
                            'chateau_ride',
                            'chateau_no',
                            'chateau_paz')
                    
                Vous avez passé un concours d'informatique. L'ensemble des noms des personnes reçues au concours est implémenté
                comme un tuple de chaînes de caractères. 
                Par exemple, si "Nguyen", "Traoré" et "Dupont" sont les noms des trois personnes reçues au concours, l'ensemble
                des personnes reçues est ("Nguyen", "Traoré", "Dupont").
            
                Afin de savoir facilement si vous êtes reçu.e ou non, vous décidez de créer une fonction est_recu_e.
            
Écrire une fonction est_recu_e qui :
            
prend comme premier paramètre un ensemble de personnes reçues sous forme d'un tuple de chaînes de caractères,
prend comme second paramètre un nom sous forme de chaîne de caractères,
                        renvoie le booléen True si le nom saisi est celui d'une personne reçue et False sinon.
                    
Tester ensuite la fonction créée.
def est_recu_e(tup_admis: tuple, nom: str) -> bool:
    """
    tup_admis est le tuple de chaînes de caractères stockant l'ensemble des noms des personnes admises au concours.
    nom est la chaîne de caractères de la personne.
    Fonction qui renvoie un booléen en fonction que la personne ayant pour nom de famille nom est reçue ou non.
    """
    admis = False 
    for elt in tup_admis:
        if elt == nom:
            admis = True 
    return admis
            On peut vérifier que :
                        est_recu_e(("Nguyen", "Traoré", "Dupont"), "Durand") renvoie bien False,
                    
                        est_recu_e(("Nguyen", "Traoré", "Dupont"), "Traoré") renvoie bien True.
                    
                Vous gérez la mini station météo de votre lycée. Cette station mesure entre autre la température extérieure
                à différents moments de la journée. L'ensemble des températures mesurées est stocké dans une liste.
                Par exemple, si la station a mesuré successivement les températures 12, 13.1, 13.7, 14 et 13.1, l'ensemble
                des températures est [12, 13.1, 13.7, 14, 13.1].
            
Vous vous rendez compte que la sonde mesurant ces températures est déréglée si bien que toutes les températures mesurées sont supérieures de 2 degrés à la température réelle.
                Afin de corriger l'ensemble des mesures obtenues, vous décidez de créer une fonction baisser2.
            
Écrire une fonction baisser2 qui :
            
prend comme paramètre une liste de nombres supposée contenir les températures mesurées,
renvoie la liste où toutes les valeurs ont été diminuées de 2.
Tester ensuite la fonction créée.
def baisser2(temperatures: list) -> list:
    """
    temperature est une liste de nombres supposée contenir les températures mesurées.
    Fonction qui la liste où toutes les valeurs ont été diminuées de 2.
    """
    # balayage de toute la liste à partir des index
    for i in len(temperatures):
        temperature[i] = temperature[i]-2   # diminution de la valeur de 2 et remplacement dans la liste
    return temperature
            
                On peut vérifier que baisser2([12, 13.1, 13.7, 14, 13.1]) renvoie bien [10, 11.1, 11.7, 12, 11.1].
            
                Écrire une fonction trouver qui prend en paramètre une liste de nombres lst et une valeurs
                val et qui renvoie la liste des indices des éléments de lst égaux à val. 
                Par exemple, trouver([12, 15, 12, 12, 16, 48, 12, 16], 12) renvoie la liste [0,2,3,6] tandis que
                trouver([12, 15, 12, 12, 16, 48, 12, 16], 17) renvoie la liste [].
            
def trouver(lst: list, val: float) -> list:
    """lst est une liste de nombres et val un nombre.
    Cette fonction renvoie la liste des indices des éléments de lst égaux à val."""
    # création d'une liste vide
    liste_indices = []
    # balayage de toute la liste des valeurs
    for i in range(len(lst)):
        if lst[i] == val : # cas d'un élément égal à la valeur cherchée
            liste_indices.append(i)
    return liste_indices
            
                On peut vérifier que trouver([12, 15, 12, 12, 16, 48, 12, 16], 12) renvoie bien [0,2,3,6] et
                que trouver([12, 15, 12, 12, 16, 48, 12, 16], 17) renvoie bien [].
            
                        Créer par compréhension la liste liste_carres des 20 premiers carrés de nombres entiers naturels impairs.
                    
                        Proposer un script permet d'additionner les termes de cette liste liste_carres.
                    
Les 20 premiers nombres impairs sont de la forme $2n+1$ avec $n$ compris entre $0$ et $19$ ; $n$ varie donc entre $1$ et $39$. Il a donc au moins deux manières de créer la liste demandée :
Méthode 1 : balayage de tous les nombres de la forme $2n+1$ avec $n$ compris entre $0$ et $19$ :
liste_carres = [(2n+1)**2 for n in range(20)]
            Méthode 2 : balayage de tous les nombres impairs $k$ entre $1$ et $39$ :
liste_carres = [k**2 for k in range(40) if k%2 ==1]
            
                        La liste liste_carres contenant tous les carrés des 20 premiers nombre entiers impairs :
                    
somme = 0 # initialisation de la variable servant à stocker progressivement la somme calculée
for elt in liste_carres:
    somme = somme + elt     # évolution de la somme
# La variable somme contient finalement la somme attendue.
            
                        Écrire une fonction epaissir qui prend en paramètre une liste de nombres lst et un nombre
                        entier non nul n
                        et qui renvoie le tableau 2D (ou matrice) formées de n lignes, toutes identiques à la liste lst.
                        Par exemple, epaissir([0, 1, 1, 0, 1, 1, 1, 0, 0, 1], 4) renvoie la liste 
[[0, 1, 1, 0, 1, 1, 1, 0, 0, 1],
 [0, 1, 1, 0, 1, 1, 1, 0, 0, 1],
 [0, 1, 1, 0, 1, 1, 1, 0, 0, 1],
 [0, 1, 1, 0, 1, 1, 1, 0, 0, 1]]Rajouter les préconditions permettant d'assurer le fait que les arguments saisis sont corrects.
1.
# En utilisant la compréhension de liste
def epaissir(lst: list, n: int) -> list:
    """lst est une liste et n est un entier naturel non nul.
    Fonction qui renvoie une liste de n listes, toutes identiques à lst"""
    return [lst for i in range(n)]
# En utilisant l'extension de liste
def epaissir(lst: list, n: int) -> list:
    """lst est une liste et n est un entier naturel non nul.
    Fonction qui renvoie une liste de n listes, toutes identiques à lst"""
    mat = []
    for i in range(n):
        mat.append(lst)
    return mat2. Rajout de la précondition :
# Préconditions à rajouter après la documentation
    assert type(lst) is list, "le premier argument doit être une liste"
    assert type(n) is int, "le second argument doit être un entier"
    assert n > 0, "le second argument doit être strictement positif"Propriétaire des ressources ci-dessous : ministère de l'Éducation nationale et de la jeunesse, licence CC BY SA NC
Voici une sélection de questions issues de la banque nationale de sujets, répondez à ces questions (attention, cette sélection n'est pas exhaustive).
                Quel est le type de l'expression f(4) si la fonction f est définie par : 
def f(x):
    return (x, x**2)Réponses :
A- un entier
B- un flottant
C- une liste
D- un tuple
On considère le code suivant :
def s(tuple1, tuple2):
    (x1, y1) = tuple1
    (x2, y2) = tuple2
    return (x1+x2, y1+y2)
                Que renvoie l'appel s((1, 3), (2, 4)) ?
            
Réponses :
A- le tuple $(3, 7)$
B- le tuple $(4, 6)$
C- un entier
D- une erreur
On exécute le code suivant :
t = [1, 2, 3, 4, 5, 6, 7, 8, 9]
v = [c for c in t if c%3 == 0]
                Quelle est la valeur de la variable v à la fin de cette exécution ?
            
Réponses :
A- 18
B- [1, 4, 7]
C- [3, 6, 9]
D- [1, 2, 3, 4, 5, 6, 7, 8, 9]
                Quelle est la valeur de l'expression [[i, 2*i] for i in range(3)] ?
            
Réponses :
A- [0, 0, 1, 2, 2, 4]
B- [[0, 0], [1, 2], [2, 4]]
C- [1, 2, 2, 4, 3, 6]
D- [[1, 2], [2, 4], [3, 6]]
                Si on tape dans la console d'exécution la commande : 
                [1, 4, 3] + [2, 4, 5] 
                qu'obtient-on ?
            
Réponses :
A- [3, 8, 8]
B- [19]
C- [1, 4, 3, 2, 4, 5]
D- un message d'erreur car l'addition n'est pas compatible avec les listes
                Quelle affectation permet de donner à L la valeur [1, 9, 25, 49, 81] ?
            
Réponses :
                A- L = [i*2 for i in range(9) if i%2 == 0]
            
                B- L = [i**2 for i in range(10) if i%2 == 0]
            
                C- L = [i**2 for i in range(10) if i%2 == 1]
            
                D- L = [i**2 for i in range(10) if i//2 == 1]
            
                On construit une liste L de la façon suivante :
            
L = []
for i in range(1, 11, 2):
    L.append(5*i)
                et on obtient ainsi la liste [5, 15, 25, 35, 45].
            
On pourrait aussi procéder de la façon suivante :
L = []
# ligne 1 .......
while i < 11:
    L.append(5*i)
    # ligne 2 .......Que faudrait-il écrire en ligne 1 et en ligne 2 pour obtenir le même résultat ?
Réponses :
                A- i = 0 en ligne 1, et i = i + 1 en ligne 2
            
                B- i = 0 en ligne 1, et i = i + 2 en ligne 2
            
                C- i = 1 en ligne 1, et i = i + 1 en ligne 2
            
                D- i = 1 en ligne 1, et i = i + 2 en ligne 2
            
Une table d'un fichier client contient le nom, le prénom et l'identifiant des clients sous la forme :
clients = [("Dupont", "Paul", 1),
           ("Durand", "Jacques", 2),
           ("Dutronc", "Jean", 3),
           ...]
                En supposant que plusieurs clients se prénomment Jean, que vaut la variable x après l'exécution du code suivant ?
            
x = []
for i in range(len(clients)):
    if clients[i][1] == "Jean":
       x = clients[i]Réponses :
A- Une liste de tuples des noms, prénoms et numéros de tous les clients prénommés Jean
B- Une liste des numéros de tous les clients prénommés Jean
C- Un tuple avec le nom, prénom et numéro du premier client prénommé Jean
D- Un tuple avec le nom, prénom et numéro du dernier client prénommé Jean
On exécute l'instruction suivante :
T = [[12, 13, 14, 15],
	 [24, 25, 26, 27],
	 [35, 36, 49, 33],
	 [61, 53, 55, 58]]Quelle expression parmi les quatre suivantes a pour valeur 26 ?
Réponses :
                A- T[1][2]
            
                B- T[2][1]
            
                C- T[2][3]
            
                D- T[3][2]
            
                Laquelle de ces expressions a pour valeur la liste [[0, 1, 2], [3, 4, 5], [6, 7, 8]] ?
            
Réponses :
                A- [[i+j for i in range(3)] for j in range(3)]
            
                B- [[i]*3 for i in range(3)]*3
            
                C- [[i+j*3 for i in range(3)] for j in range(3)]
            
                D- [[i+j for i in range(3)] for j in range(3)]*3
            
                On définit une grille G remplie de 0, sous la forme d'une liste de listes, où toutes les sous-listes ont le
                même nombre d'éléments.
            
G = [[0, 0, 0, …, 0],
     [0, 0, 0, …, 0],
     [0, 0, 0, …, 0],
     ……
     [0, 0, 0, …, 0]]
                On appelle hauteur de la grille le nombre de sous-listes contenues dans G et largeur
                de la grille le nombre d'éléments dans chacune de ces sous-listes. Comment peut-on les obtenir ?
            
Réponses :
                A- hauteur = len(G[0])
                    largeur = len(G)
            
                B- hauteur = len(G)
                    largeur = len(G[0])
            
                C- hauteur = len(G[0])
                    largeur = len(G[1])
            
                D- hauteur = len(G[1])
                    largeur = len(G[0])
            
On a défini :
mendeleiev = [['H', '.', '.', '.', '.', '.', '.', 'He'],
              ['Li', 'Be', 'B', 'C', 'N', 'O', 'Fl', 'Ne'],
              ['Na', 'Mg', 'Al', 'Si', 'P', 'S', 'Cl', 'Ar']]Comment construire la liste des trois premiers gaz rares, c'est-à-dire la liste des éléments de la dernière colonne ?
Réponses :
                A- gaz_rares = [periode[7] for periode in mendeleiev]
            
                B- gaz_rares = [periode for periode in mendeleiev[7]]
            
                C- gaz_rares = [periode for periode[7] in mendeleiev]
            
                D- gaz_rares = [periode[8] for periode in mendeleiev]
            
On considère la liste de listes suivante :
tictactoe = [['X', 'O', 'O'],
             ['O', 'O', 'O'],
             ['O', 'O', 'X']]
                Quelle instruction permet d'obtenir une diagonale de 'X' ?
            
Réponses :
                A- tictactoe[3] = 'X'
            
                B- tictactoe[4] = 'X'
            
                C- tictactoe[1][1] = 'X'
            
                D- tictactoe[2][2] = 'X'
            
                On définit la liste L ainsi : L = [[1], [1, 2], [1, 2, 3]]. 
                Des égalités suivantes, une seule est fausse. Laquelle ?
            
Réponses :
                A- len(L[0]) == 1
            
                B- len(L) == 6
            
                C- len(L[2]) == 3
            
                D- L[2][2] == 3
            
On souhaite écrire une fonction qui renvoie le maximum d'une liste d'entiers :
def maximum(L):
    m = L[0]
    for i in range(1, len(L)):
        if .........:
            m = L[i]
    return mPar quoi faut-il remplacer les pointillés pour que cette fonction produise bien le résultat attendu ?
Réponses :
                A- i > m
            
                B- L[i] > m
            
                C- L[i] > L[i-1]
            
                D- L[i] > L[i+1]
            
On considère le code incomplet suivant qui recherche le maximum dans une liste.
liste = [5, 12, 15, 3, 15, 17, 29, 1]
iMax = 0
for i in range(1, len(liste)):
    ............
       iMax = i
print (liste[iMax])Par quoi faut-il remplacer la ligne pointillée ?
Réponses :
                A- if i > iMax:
            
                B- if liste[i] > liste[iMax]:
            
                C- if liste[i] > iMax:
            
                D- if i > liste[iMax]:
            
                On définit la fonction f suivante qui prend en argument une liste t d'entiers :
            
def f(t):
    n = len(t)
    for i in range(n-1):
        for j in range(i+1, n):
            if t[i] == t[j]:
                return True
    return False
                Pour quelle valeur de t, f(t) vaut-elle True ?
            
Réponses :
                A- [[2, 3], [3, 4], [4, 5], [2, 3]]
            
                B- [[2, 2], [3, 4], [4, 5], [2, 3]]
            
                C- [[2, 3], [3, 2], [4, 5], [5, 4]]
            
                D- [[3, 3], [4, 4], [5, 5], [6, 6]]
            
Les QCM suivants sont issus de https://genumsi.inria.fr.
                Laquelle des propositions suivantes permet de créer un p-uplet nommé p contenant la chaîne 'foo' ?
            
Réponses :
                A- p = puplet('foo')
            
                B- p = ('foo',)
            
                C- p = ('foo')
            
D- On ne peut pas créer un tuple comportant 1 seul élément !
Qu'affiche le programme suivant ?
tuple = (1, 5, 7, 9, 10, 15)
tuple[5] = 2
print("tuple=", tuple)Réponses :
                A- (1, 2, 7, 9, 10, 15)
            
                B- (1, 5, 7, 9, 10, 2)
            
C- TypeError : 'tuple' object does not support item assignment
                D- (1, 5, 7, 9, 2, 15)
            
Qu'affiche le programme suivant ?
tuple = (1, 5, 7, 9, 10, 15)
print("tuple[5] = ", tuple[5])Réponses :
                A- tuple[5] = 5
            
                B- tuple[5] = '5'
            
                C- tuple[5] = 15
            
                D- tuple[5] = 10
            
Il faut actualiser la page pour changer de question. Propriétaire de la ressource : le site GeNumsi en licence CC BY_NC-SA
        
 Les différents
                auteurs mettent l'ensemble du site à disposition selon les termes de la licence Creative
            Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0
            International